# 还必须导入HttpResponse模块，才可以将python定义的内容返回给前端去显示
import json
import os
import time

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage, InvalidPage
from django.db import transaction
from django.http import HttpResponse, StreamingHttpResponse
from django.http import JsonResponse
from django.shortcuts import render, redirect
# 这个req形参是浏览器发送给服务端的全部信息，服务端打包后传入到该函数的一个对象
from django.utils.encoding import escape_uri_path

from blog.models import Account
from blog.models import AccountSerializer
from common import common_response, format_conversion

# 引入定时任务的执行

# 行内用“#”号，行间注释写在两组连续三单引号之间：’’’

'''针对单前导下划线：_var（只是约定，给程序员提示），单末尾下划线：var_（为了避免与Python关键字冲突）， 双前导下划线：__var(这个Python解释器会重命名_+类名+__var)， 双前导和末尾下划线：__var__（这个是系统默认的，一般不要使用），
单下划线：_（临时变量使用）的作用，参照https://blog.csdn.net/tcx1992/article/details/80105645
__doc__：获取到注释内容
__name__：获取到函数的名称
__file__：获取到当前的文件路径
比如：
def my_python():
    """This is my python"""
    return ("From my python!")

print my_python()
print(my_python.__doc__)
print (my_python.__name__)
print __file__
结果如下：
From my python!
This is my python
my_python
D:/mysite/blog/views.py
'''

'''针对__all__变量，如果使用from 模块 import *导入模块，则只能调用模块中__all__列表中指定的方法、类、变量，如果使用import 模块导入模块，则__all__不起作用'''
__all__ = ['show_time', 'get_all_account_list', 'get_account_list_by_paginator',
           'get_account_list_by_paginator_html_view']

'''注意普通方法没有self，只有定义的类方法(类中的方法)才会有self，self表示对象本身，谁调用就是谁，比如 p = Person('张三', 25)中Person类中的__init__初始化方法中的self就表示p'''


class Root(object):
    def __init__(self, y):
        self.x = '这是属性'
        self.y = y

    '''他是一个自我描述的方法，该方法由object提供，由于所有类都是object类的子类，所以都会继承该方法，但是由于object提供的这个__repr__方法总是返回一个对象， （  类名 + obejct  at + 
    内存地址  ），这个值并不能真正实现自我描述的功能！！！因此，如果你想在自定义类中实现  “自我描述” 的功能，那么必须重写 __repr__ 方法，返回详细的自我描述信息，相当于java的toString方法'''

    def __repr__(self):
        # 任意值转为字符串：将它传入repr()即%r 或str() 即%s函数
        #  函数str() 用于将值转化为适于人阅读的形式，而repr() 转化为供解释器读取的形式
        return 'Root类，包含x= %r 这1个实例属性' % self.x

    def fun(self):
        print(self.x)
        print('这是方法')
        '''
        None表示空值，它是一个特殊 Python 对象, None的类型是NoneType，None在 Python 解释器启动时自动创建, 解释器退出时销毁。
        在一个解释器进程中只有一个 None 存在，None有自己的数据类型NoneType，不能创建其他NoneType对象（它只有一个值None）说明None是惟一的，
        因为不可能有其他对象会使用 None 已占用的内存(它就是占了个坑)。
        None和任何其他的数据类型比较永远返回False。
        None与0、空列表、空字符串不一样。
        is: 指向同一内存地址(相当于java中的==)
        ==: 指向的内存地址中的内容是相同的(相当于java中的equals方法)
        针对字符串类型的变量，比如a='123' b='123' 那么a和b的is和==比较都返回True，因为有字符串池的概念。
        对于所有没有 return 语句的函数定义，Python 都会在末尾加上 return None，使用不带值的 return 语句（也就是只有 return 关键字本身），那么就返回 None， 
        print() 就返回 None。
        首先我们要知道None,空列表[],空元组(),空字典{},0都是被程序判断为False,所以要判断对象是否为空，可以用if not x的方法：
            a={}
            if not a :
                print("Empty")
            else :
                print("Not Empty"
        另外，对于list，根据PEP8,不推荐用len(list)==0来判断。
        
        '''
        return None

    '''
    python中cls代表的是类的本身，相对应的self则是类的一个实例对象， cls可以在静态方法中使用，并通过cls()方法来实例化一个对象。
    如下：
        class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
            print('self:', self)
    
        # 定义一个build方法，返回一个person实例对象，这个方法等价于Person()。
        @classmethod
        def build(cls):
            # cls()等于Person()
            p = cls("Tom", 18)
            print('cls:', cls)
            return p
    
    
        if __name__ == '__main__':
            person = Person.build()
            print(person, person.name, person.age)
            
    运行结果如下：
    self: <__main__.Person object at 0x00000254D9A61B80>
    cls: <class '__main__.Person'>
    <__main__.Person object at 0x00000254D9A61B80> Tom 18        
            
    参数arg、*args、**kwargs三个参数的位置必须是一定的。必须是(arg,*args,**kwargs)这个顺序，否则程序会报错。
    **kwargs 打包关键字参数成dict给函数体调用, *args 用来将参数打包成tuple给函数体调用
    比如：
       def function(arg,*args,**kwargs):
           print(arg,args,kwargs)
       function(6,7,8,9,a=1, b=2, c=3)  
      打印：
         6,(7,8,9){'c':3,'a':1,'b':2} 
             
        
    '''

    @classmethod
    def create_module(cls, *args, **kwargs):
        """ Create a built-in module """
        pass

    '''
    __new__() 方法是在类准备将自身实例化时调用。
    __new__() 方法始终都是类的静态方法，即使没有被加上静态方法装饰器。
    重写__new__方法，返回这个重写的__new__方法。
    事实上如果（新式）类中没有重写__new__()方法，即在定义新式类时没有重新定义__new__()时，Python默认是调用该类的直接父类的__new__()方法来构造该类的实例，
    如果该类的父类也没有重写__new__()，那么将一直按此规矩追溯至object的__new__()方法，因为object是所有新式类的基类。
    比如：
       class F1(object):
        　　#重写__new__方法，返回这个重写的__new__方法
            @staticmethod
            def __new__(cls, *args, **kwargs):
                return 123

       obj=F1() #实例化对象是谁取决于__new__方法,__new__返回什么就是什么
       print(obj,type(obj))  #打印结果：123 <class 'int'>
    '''


class A(Root):
    def __init__(self):
        """加入super(A, self).__init__()时才能使用 a= A()，a.fun(), a.x来调用A的父类Root的属性和方法"""
        super(A, self).__init__(1)
        print('实例化时执行')


"""
上下文管理协议，即with语句，为了让一个对象兼容with语句，必须在这个对象的类中（下面的Open类中）声明__enter__和__exit__方法
"""


class Open:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
        # return self

    '''__exit__中的三个参数分别代表异常类型，异常值和追溯信息,
    with语句中代码块出现异常，则with后的代码都无法执行，__exit__返回值为True,那么异常会被清空，就好像啥都没发生一样，with后的语句正常执行'''

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代码块执行完毕时执行我啊')
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        return True


"""
操作文件对象的时候可以这么写，使用with语句的目的就是把代码块放入with中执行，with结束后，自动完成清理工作，无须手动干预
在需要管理一些资源比如文件，网络连接和锁的编程环境中，可以在Open类中的__exit__方法定制自动释放资源的机制，比如文件流的关闭（f.close()），你无须再去关心这个问题，这将大有用处
"""
with Open('a.txt') as f:
    print('=====>执行代码块')
    raise AttributeError('***着火啦,救火啊***')
# 如果Open类中的__exit__方法返回值为True，则下面的代码会执行，如果with语句中代码块出现异常，则下面的代码都无法执行
print('0' * 100)


def show_time(req):
    # return HttpResponse("Welcome to my blog!")
    t = time.ctime()
    return render(req, "index.html", locals())


# 获取所有账户列表
def get_all_account_list(request):
    # 和前端约定的返回格式
    # response_result = {"message": 'success', "code": '0', "data": []}
    try:
        if request.session.get('is_login', None):
            account_list = Account.objects.all().order_by('-account_id')  # 按照account_id倒序
            res = AccountSerializer(account_list, many=True)
            res_data = res.data
            if not res_data:
                result = common_response.handle_response([])
            else:
                # 响应中的字段驼峰显示
                res_data = format_conversion.camel_dict(res_data)
                result = common_response.handle_response(res_data)
            # result = {
            #     'code': 0,
            #     'message': 'success',
            #     'data': res.data,
            # }
        else:
            result = common_response.handle_response("user is not login!", 1)
    except Exception as e:
        result = common_response.handle_response([], 1)
        print("get_all_account_list exception: {0}".format(e))
        # json_dumps_params={'ensure_ascii': False} 这个表示json中不出现unicode格式的乱码
    return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
    # # 序列化为 Python 对象
    # response_result["data"] = serializers.serialize('python', results)
    # # 转换为 JSON 字符串并返回
    # return HttpResponse(json.dumps(response_result), content_type="application/json")


# 分页获取账户列表
def get_account_list_by_paginator(request):
    if request.session.get('is_login', None):
        # 获取 url 后面的 page 参数的值, 首页不显示 page 参数, 默认值是 1
        page = request.GET.get('page')
        page_data = {'totals': 0, 'page': int(page), 'pages': 1, 'list': []}
        if request.method == "GET":
            account_list = Account.objects.all().order_by('-account_id')  # 按照account_id倒序
            res = AccountSerializer(account_list, many=True)
            # 响应中的字段驼峰显示
            result = format_conversion.camel_dict(res.data)
            # 将数据按照规定每页显示 2 条, 进行分割
            paginator = Paginator(result, 2)
            try:
                paginator_page = paginator.page(page)
                totals = paginator.count
                page_data.update({'totals': totals})
                pages = paginator.num_pages
                page_data.update({'pages': pages})
                # 当前页的列表
                res_page_data = list(paginator_page)
                page_data.update({'list': res_page_data})
                result = common_response.handle_response(page_data)
                return JsonResponse(result, safe=False, json_dumps_params={'ensure_ascii': False})
            # todo: 注意捕获异常
            except PageNotAnInteger:
                # 如果请求的页数不是整数, 返回第一页。
                paginator_page = paginator.page(1)
                totals = paginator.count
                page_data.update({'totals': totals})
                pages = paginator.num_pages
                page_data.update({'pages': pages})
                # 当前页的列表
                res_page_data = list(paginator_page)
                page_data.update({'list': res_page_data})
                result = common_response.handle_response(res_page_data)
                return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
            except InvalidPage:
                page_data.update({'totals': 0})
                page_data.update({'pages': 1})
                page_data.update({'list': []})
                return JsonResponse(common_response.handle_response(page_data, 1),
                                    json_dumps_params={'ensure_ascii': False})
            except EmptyPage:
                # 如果请求的页数不在合法的页数范围内，返回结果的最后一页。
                paginator_page = paginator.page(paginator.num_pages)
                totals = paginator.count
                page_data.update({'totals': totals})
                pages = paginator.num_pages
                page_data.update({'pages': pages})
                # 当前页的列表
                res_page_data = list(paginator_page)
                page_data.update({'list': res_page_data})
                result = common_response.handle_response(res_page_data)
                return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
            except Exception as e:
                print("get_account_list_by_paginator exception: {0}".format(e))
                page_data.update({'totals': 0})
                page_data.update({'pages': 1})
                page_data.update({'list': []})
                # 行尾输入一个反斜杠加一个空格（’\ ‘），再换行。如果行尾语法明显未完成（比如以逗号结尾），可以直接续行，比如下面的代码以逗号续行
                return JsonResponse(common_response.handle_response(page_data, 1),
                                    json_dumps_params={'ensure_ascii': False})
        else:
            print("not support request method!")
            page_data.update({'totals': 0})
            page_data.update({'pages': 1})
            page_data.update({'list': []})
            return JsonResponse(common_response.handle_response(page_data, 1),
                                json_dumps_params={'ensure_ascii': False})

    else:
        return JsonResponse(common_response.handle_response("user is not login!", 1),
                            json_dumps_params={'ensure_ascii': False})


# 分页获取账户列表并使用模板渲染
def get_account_list_by_paginator_html_view(request):
    if request.session.get('is_login', None):
        # 获取 url 后面的 page 参数的值, 首页不显示 page 参数, 默认值是 1
        page = request.GET.get('page')
        if request.method == "GET":
            account_list = Account.objects.all().order_by('-account_id')  # 按照account_id倒序
            res = AccountSerializer(account_list, many=True)
            # 响应中的字段驼峰显示
            result = format_conversion.camel_dict(res.data)
            # 将数据按照规定每页显示 2 条, 进行分割
            paginator = Paginator(result, 2)
            try:
                paginator_page = paginator.page(page)
            # todo: 注意捕获异常
            except PageNotAnInteger:
                # 如果请求的页数不是整数, 返回第一页。
                paginator_page = paginator.page(1)
            except InvalidPage:
                # 如果请求的页数不存在, 重定向页面
                return HttpResponse('找不到页面的内容')
            except EmptyPage:
                # 如果请求的页数不在合法的页数范围内，返回结果的最后一页。
                paginator_page = paginator.page(paginator.num_pages)
            except Exception as e:
                print("get_account_list_by_paginator_html exception: {0}".format(e))
                return HttpResponse('服务端发生异常')
        else:
            print("not support request method!")
            return HttpResponse('请求方法不支持')
    else:
        return HttpResponse('user is not login!')
    template_view = 'page.html'
    return render(request, template_view, {'accounts': paginator_page})


# 根据账户主键获取单个账户
def get_account_by_account_id(request):
    try:
        if request.session.get('is_login', None):
            request_method = request.method
            if request_method == 'GET':
                request_data = format_conversion.underline_dict(request.GET)
                account_id = request_data.get('account_id')
                if not account_id:
                    print('account_is is not None!')
                    return JsonResponse(common_response.handle_response({}), json_dumps_params={'ensure_ascii': False})
                else:
                    # 根据账号主键获取单个账号
                    single_account = Account.objects.filter(account_id=account_id).values()
                    if single_account.count() == 0:
                        return JsonResponse(common_response.handle_response({}),
                                            json_dumps_params={'ensure_ascii': False})
                    else:
                        single_account = list(single_account)
                        single_account = single_account[0]
                        # 时间格式化
                        create_time = {'create_time': single_account['create_time'].strftime("%Y-%m-%d %H:%M:%S")}
                        single_account.update(create_time)
                        update_time = {'update_time': single_account['update_time'].strftime("%Y-%m-%d %H:%M:%S")}
                        single_account.update(update_time)
                        res_data = format_conversion.camel_dict(single_account)
                        result = common_response.handle_response(res_data)
                        return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
            # elif request.method == "POST":
            #     # 表单类型数据的获取
            #     account_id = request.POST.get('account_id')
            #     if not account_id:
            #         # 非表单数据的获取，Django无法自动解析，可以通过request.body属性获取最原始的请求体数据，自己按照请求体格式（JSON、XML等）进行解析。request.body返回bytes类型
            #         req_body = json.loads(request.body.decode('utf-8'))
            #         request_data = format_conversion.underline_dict(req_body)
            #         account_id = request_data['account_id']
            #     single_account = Account.objects.filter(account_id=account_id).values()
            #     if single_account.count() == 0:
            #         return JsonResponse(common_response.handle_response({}), json_dumps_params={'ensure_ascii': False})
            #     else:
            #         single_account = list(single_account)
            #         single_account = AccountSerializer(single_account, many=True)
            #         res_data = format_conversion.camel_dict(single_account[0])
            #         result = common_response.handle_response(res_data)
            #         return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
            else:
                print("not support request method!")
                return JsonResponse(common_response.handle_response({}, 1), json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("get_account_by_account_id exception: {0}".format(e))
        return JsonResponse(common_response.handle_response({}, 1), json_dumps_params={'ensure_ascii': False})


# 单个创建账户
# ================客户端请求如下=========================
#     POST http://127.0.0.1:8000/create_account/
#     Accept: */*
#     Cache-Control: no-cache
#     Content-Type: application/json
#
#     {
#       "accountName": "刘起",
#       "balance": "50"
#     }
def create_account(request):
    try:
        if request.session.get('is_login', None):
            with transaction.atomic():  # 开启事务
                if request.method == "POST":
                    req_body = json.loads(request.body.decode('utf-8'))
                    request_data = format_conversion.underline_dict(req_body)
                    request_data = Account(**request_data)  # 加一个星号表示这个变量是元组/列表，加两个星号表示这个参数是字典
                    request_data.save()
                    # 获取插入成功后的账户信息
                    account_id = request_data.account_id
                    single_account = Account.objects.filter(account_id=account_id).values()
                    single_account = list(single_account)
                    single_account = single_account[0]
                    # 时间格式化
                    create_time = {'create_time': single_account['create_time'].strftime("%Y-%m-%d %H:%M:%S")}
                    single_account.update(create_time)
                    update_time = {'update_time': single_account['update_time'].strftime("%Y-%m-%d %H:%M:%S")}
                    single_account.update(update_time)
                    res_data = format_conversion.camel_dict(single_account)
                    result = common_response.handle_response(res_data)
                    return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
                else:
                    print("not support request method!")
                    return JsonResponse(common_response.handle_response(0, 1),
                                        json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("create_account exception: {0}".format(e))
        return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})


# 批量创建账号
# ===================批量创建账号的请求========================
#     POST http://127.0.0.1:8000/patch_create_account/
#     Accept: */*
#     Cache-Control: no-cache
#     Content-Type: application/json
#
#     [
#       {
#         "accountName": "王涛",
#         "balance": "29"
#       },
#       {
#         "accountName": "谢欢",
#         "balance": "30"
#       }
#     ]
def patch_create_account(request):
    try:
        if request.session.get('is_login', None):
            with transaction.atomic():  # 开启事务
                if request.method == "POST":
                    req_body = json.loads(request.body.decode('utf-8'))
                    req_body_list = list(req_body)
                    account_list_to_insert = list()
                    for i in req_body_list:
                        account_list_to_insert.append(
                            Account(account_name=i['accountName'], balance=i['balance']))
                    Account.objects.bulk_create(account_list_to_insert)
                    return JsonResponse(common_response.handle_response(len(account_list_to_insert)),
                                        json_dumps_params={'ensure_ascii': False})

                else:
                    print("not support request method!")
                    return JsonResponse(common_response.handle_response(0, 1),
                                        json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("patch_create_account exception: {0}".format(e))
        return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})


# 单个更新账户
# =================请求参数=======================
#     PATCH http://127.0.0.1:8000/update_account/
#     Accept: */*
#     Cache-Control: no-cache
#     Content-Type: application/json
#
#     {
#       "accountId": 15,
#       "accountName": "黄泉",
#       "balance": "45"
#     }
def update_account(request):
    try:
        if request.session.get('is_login', None):
            with transaction.atomic():  # 开启事务
                if request.method == "PATCH" or request.method == "PUT":
                    req_body = json.loads(request.body.decode('utf-8'))
                    request_data = format_conversion.underline_dict(req_body)
                    if 'account_id' not in request_data.keys():
                        print("account_id is Null!")
                        return JsonResponse(common_response.handle_response(0, 1),
                                            json_dumps_params={'ensure_ascii': False})
                    account_id = request_data['account_id']
                    if not account_id:
                        print("account_id is Null!")
                        return JsonResponse(common_response.handle_response(0, 1),
                                            json_dumps_params={'ensure_ascii': False})
                    account = Account.objects.get(account_id=account_id)
                    if not account:
                        print("account is not exist!")
                        return JsonResponse(common_response.handle_response(0, 1),
                                            json_dumps_params={'ensure_ascii': False})
                    if 'balance' in request_data.keys():  # 判断balance是否存在request_data字典中
                        balance = request_data['balance']
                        if balance is not None and len(balance) != 0 and balance.strip() != '':
                            account.balance = balance
                    if 'account_name' in request_data.keys():  # 判断account_name是否存在request_data字典中
                        account_name = request_data['account_name']
                        if account_name is not None and len(account_name) != 0 and account_name.strip() != '':
                            account.account_name = account_name
                    account.save()
                    # 获取更新后的账户
                    single_account = Account.objects.filter(account_id=account_id).values()
                    single_account = list(single_account)
                    single_account = single_account[0]
                    # 时间格式化
                    create_time = {'create_time': single_account['create_time'].strftime("%Y-%m-%d %H:%M:%S")}
                    single_account.update(create_time)
                    update_time = {'update_time': single_account['update_time'].strftime("%Y-%m-%d %H:%M:%S")}
                    single_account.update(update_time)
                    res_data = format_conversion.camel_dict(single_account)
                    result = common_response.handle_response(res_data)
                    return JsonResponse(result, json_dumps_params={'ensure_ascii': False})
                else:
                    print("not support request method!")
                    return JsonResponse(common_response.handle_response(0, 1),
                                        json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("update_account exception: {0}".format(e))
        return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})


# 批量更新账户
# ===============请求参数=========================
#     PATCH http://127.0.0.1:8000/patch_update_account/
#     Accept: */*
#     Cache-Control: no-cache
#     Content-Type: application/json
#
#     [
#       {
#         "accountId": 15,
#         "accountName": "周凯",
#         "balance": "78"
#       },
#       {
#         "accountId": 10,
#         "accountName": "茂云",
#         "balance": "870"
#       }
#     ]
def patch_update_account(request):
    try:
        if request.session.get('is_login', None):
            with transaction.atomic():  # 开启事务
                if request.method == "PATCH" or request.method == "PUT":
                    req_body = json.loads(request.body.decode('utf-8'))
                    req_body_list = list(req_body)
                    account_list_to_update = list()
                    for i in req_body_list:
                        if 'accountId' not in i.keys() or not i['accountId']:
                            print("account_id is Null!")
                            return JsonResponse(common_response.handle_response(0, 1),
                                                json_dumps_params={'ensure_ascii': False})
                        account_id = i['accountId']
                        single_account = Account.objects.filter(account_id=account_id).values()
                        if single_account.count() == 0:
                            print('account is Null!')
                            return JsonResponse(common_response.handle_response(0, 1),
                                                json_dumps_params={'ensure_ascii': False})
                        account_list_to_update.append(
                            Account(account_id=i['accountId'], account_name=i['accountName'], balance=i['balance'],
                                    update_time=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))))
                    Account.objects.bulk_update(account_list_to_update, ['account_name', 'balance', 'update_time'])
                    return JsonResponse(common_response.handle_response(len(account_list_to_update)),
                                        json_dumps_params={'ensure_ascii': False})

                else:
                    print("not support request method!")
                    return JsonResponse(common_response.handle_response(0, 1),
                                        json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("patch_update_account exception: {0}".format(e))
        return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})


# 单个删除账户
# ====================请求数据=============================
#     DELETE http://127.0.0.1:8000/delete_account?accountId=2
#     Accept: */*
#     Cache-Control: no-cache
#     Content-Type: application/x-www-form-urlencoded
def delete_account(request):
    try:
        if request.session.get('is_login', None):
            request_method = request.method
            if request_method == 'DELETE':
                request_data = format_conversion.underline_dict(request.GET)
                account_id = request_data.get('account_id')
                if not account_id:
                    print('account_id is Null!')
                    return JsonResponse(common_response.handle_response(0, 1),
                                        json_dumps_params={'ensure_ascii': False})
                single_account = Account.objects.filter(account_id=account_id).values()
                if single_account.count() == 0:
                    print('account is Null!')
                    return JsonResponse(common_response.handle_response(0, 1),
                                        json_dumps_params={'ensure_ascii': False})
                Account.objects.filter(account_id=account_id).delete()
                return JsonResponse(common_response.handle_response(1),
                                    json_dumps_params={'ensure_ascii': False})
            else:
                print("not support request method!")
                return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("delete_account exception: {0}".format(e))
        return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})


# 批量删除
# ==============请求数据=====================
#     DELETE http://127.0.0.1:8000/patch_delete_account
#     Accept: */*
#     Cache-Control: no-cache
#     Content-Type: application/json
#
#     {
#       "del_list": [
#         4,
#         5
#       ]
#     }
def patch_delete_account(request):
    try:
        if request.session.get('is_login', None):
            request_method = request.method
            if request_method == 'DELETE':
                req_body = json.loads(request.body.decode('utf-8'))
                del_list = req_body['del_list']
                for account_id in del_list:
                    if not account_id:
                        print('account_id is Null!')
                        return JsonResponse(common_response.handle_response(0, 1),
                                            json_dumps_params={'ensure_ascii': False})
                    single_account = Account.objects.filter(account_id=account_id).values()
                    if single_account.count() == 0:
                        print('account is Null!')
                        return JsonResponse(common_response.handle_response(0, 1),
                                            json_dumps_params={'ensure_ascii': False})
                Account.objects.filter(
                    account_id__in=del_list).delete()  # 注意这里__in前面的字段名称，我这里账户主键的字段是account_id，可能有些表中的主键字段名称为id
                return JsonResponse(common_response.handle_response(len(del_list)),
                                    json_dumps_params={'ensure_ascii': False})
            else:
                print("not support request method!")
                return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("patch_delete_account exception: {0}".format(e))
        return JsonResponse(common_response.handle_response(0, 1), json_dumps_params={'ensure_ascii': False})


# 跳转到上传页面
def skip_upload(request):
    if request.session.get('is_login', None):
        template_view = 'upload_file.html'
        return render(request, template_view)
    else:
        return redirect('/login')


# 文件上传
def upload_file(request):
    try:
        if request.session.get('is_login', None):
            if request.method == "POST":  # 请求方法为POST时，进行处理
                my_file = request.FILES.get("my_file", None)  # 获取上传的文件，如果没有文件，则默认为None
                if not my_file:
                    return JsonResponse(common_response.handle_response("no files for upload!", 1),
                                        json_dumps_params={'ensure_ascii': False})
                destination = open(os.path.join("D:\\upload", my_file.name), 'wb+')  # 打开特定的文件进行二进制的写操作
                for chunk in my_file.chunks():  # 分块写入文件
                    destination.write(chunk)
                destination.close()
                return render(request, 'upload_success.html', {'jad_address': my_file})
                # return JsonResponse(common_response.handle_response("upload over!"),
                #                     json_dumps_params={'ensure_ascii': False})
            else:
                print("not support request method!")
                return JsonResponse(common_response.handle_response("not support request method!", 1),
                                    json_dumps_params={'ensure_ascii': False})
        else:
            return JsonResponse(common_response.handle_response("user is not login!", 1),
                                json_dumps_params={'ensure_ascii': False})
    except Exception as e:
        print("upload_file exception: {0}".format(e))
        return JsonResponse(common_response.handle_response("server exception!", 1),
                            json_dumps_params={'ensure_ascii': False})


# 文件下载
def download_file(request, file_name):
    if request.session.get('is_login', None):
        file_path = 'D:/upload/' + file_name
        print(file_path)
        if not os.path.isfile(file_path):
            return HttpResponse("Sorry but Not Found the File")

        def file_iterator(file_path, chunk_size=512):
            """
            文件生成器,防止文件过大，导致内存溢出
            :param file_path: 文件绝对路径
            :param chunk_size: 块大小
            :return: 生成器
            """
            with open(file_path, mode='rb') as f:
                while True:
                    c = f.read(chunk_size)
                    if c:
                        yield c
                    else:
                        break

        try:
            response = StreamingHttpResponse(file_iterator(file_path))
            # 以流的形式下载文件,这样可以实现任意格式的文件下载
            response['Content-Type'] = 'application/octet-stream'
            # Content-Disposition就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名
            response['Content-Disposition'] = f"attachment; filename={escape_uri_path(file_name)};"
            # response['Content-Disposition'] = 'attachment;filename="{0}"'.format(file_name)
        except:
            return HttpResponse("Sorry but Not Found the File")
    else:
        return HttpResponse("user is not login!")
    return response

# def file_iterator(file_name, chunk_size=512):
#     print(file_name, '******************')
#     with open(file_name, 'rb') as f:
#         if f:
#             yield f.read(chunk_size)
#             print('下载完成')
#         else:
#             print('未完成下载')
